﻿using ComLib.ComFun;
using IPCMessage;
using KFormBase;
using KInterfaces;
using LogLib;
using MsgPack.Serialization;
using NetMQ;
using NetMQ.Sockets;
using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MainForms
{
    public partial class MainForm : KForm
    {    
        public MainForm(bool isMainForm) : base(isMainForm)
        {
            InitializeComponent();
            InitializeCustomComponent();           
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            Initialize();
        }

        public void OnCountdownCompleted(object sender, EventArgs e)
        {
           
        }

        private void Initialize()
        {
            Log.WriteAsync("Initialize in");
            Log.WriteAsync($"应用程序启动路径:{Application.StartupPath}");                    
            this.Controls.Clear();
            Init(OnAppExited, OnAppExitRequested, TakeAdministratorAction, OnJobStateChanged);
            SwitchToModule(_appManager.StartupApp);
            Log.WriteAsync("系统初始化成功");           
            Log.WriteAsync("Initialize out");
        }

        private void ExitApp(Action afterExitedHandler = null)
        {
            Log.WriteAsync("开始关闭程序");
            SendKeys.Send("^%{UP}");
            Program.ShowTaskBar(true);
            _appManager.Exit();
            AsyncTask.StartDelayTask(2, () => this.Close(), this);
            if (afterExitedHandler != null)
            {
                AsyncTask.StartDelayTask(1, afterExitedHandler, this);
            }
        }

        private void OnAppExited(object sender, EventArgs e)
        {
            ExitApp();            
        }

        private void TakeAdministratorAction(object sender, AdministratorActionTakenEventArgs e)
        {
            switch (e.Action)
            {
                case AdministratorAction.None:
                    break;
                case AdministratorAction.About:
                    break;
                case AdministratorAction.Setting:
                    break;
                case AdministratorAction.Exit:
                    ExitApp();
                    break;
                case AdministratorAction.Reboot:
                    ExitApp(() => IPCCom.Reboot());
                    break;
                case AdministratorAction.Lock:
                    break;
                case AdministratorAction.Shutdown:
                    ExitApp(()=>IPCCom.ShutDown());
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 收到业务状态变化事件通知
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnJobStateChanged(object sender, JobStateChangedEventArgs e)
        {
            KJob job = e.Job;
            switch (job.Status)
            {
                case JobStatus.Ready:
                    break;
                case JobStatus.Started:
                    break;
                case JobStatus.Aborted:
                    break;
                case JobStatus.Cancelled:
                    break;
                case JobStatus.Error:
                    break;
                case JobStatus.Completed:
                    break;
                default:
                    break;
            }
        }

        private void OnAppExitRequested(object sender, EventArgs e)
        {
            if(MessageBox.Show(
                "点击'是'确认关闭，点击‘否‘取消关闭.",
                "是否关闭应用程序？",
                MessageBoxButtons.YesNo, 
                MessageBoxIcon.Question)
                == System.Windows.Forms.DialogResult.Yes)
            {
                Program.ShowTaskBar(true);
                _appManager.Exit();
                AsyncTask.StartDelayTask(3, ()=> 
                {
                    this.Close(); 
                }, 
                this);
            }       
        }
   
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            Program.ShowTaskBar(true);
            Program.ShowStartButton(true);
            Log.WriteAsync("====================[" + _appName + "Close]====================");
            Log.Exit();
        }

        #region IPC Control
        private MessagePackSerializer<IPCRequestMessage> serializerRequest = null;

        private MessagePackSerializer<IPCResponseMessage> serializerResponse = null;

        private NetMQSocket clientSocket = null;

        private bool ClientConnected = false;

        private AutoResetEvent autoEvent = null;

        private async void StartIPCClient()
        {
            serializerRequest = MessagePackSerializer.Get<IPCRequestMessage>();
            serializerResponse = MessagePackSerializer.Get<IPCResponseMessage>();
            autoEvent = new AutoResetEvent(false);
            await Task.Run(() => {
                using (clientSocket = new RequestSocket(">tcp://127.0.0.1:5555"))
                {
                    ClientConnected = true;
                    Log.WriteAsync("Client has Started...");
                    while (true)
                    {
                        autoEvent.WaitOne();
                        byte[] buffer = clientSocket.ReceiveFrameBytes();
                        IPCResponseMessage responseMsg = serializerResponse.UnpackSingleObject(buffer);
                        Log.WriteAsync($"Response data from server:{responseMsg.ErrorCode}:{responseMsg.Message}");
                        Log.WriteAsync($"Response command success:{responseMsg.Success}");
                        Log.WriteAsync($"Response command ElapsedSecond:{responseMsg.ElapsedSecond}");
                        Log.WriteAsync($"Response command OutParams:{responseMsg.OutParams}");
                        OnServerResponsed(responseMsg);
                        if (responseMsg.ExcuteCommand == RequestCommand.ExitApp)
                        {
                            break;
                        }
                    }
                    ClientConnected = false;
                }
            });
            Log.WriteAsync("Net Socket Exit.");
        }

        /// <summary>
        /// 当收到服务端回复消息时,
        /// </summary>
        /// <param name="responseMsg"></param>
        private void OnServerResponsed(IPCResponseMessage responseMsg)
        {
            if (this.InvokeRequired)
            {
                Action<IPCResponseMessage> outHandler = new Action<IPCResponseMessage>(OnServerResponsed);
                this.BeginInvoke(outHandler, new object[] { responseMsg });
                return;
            }
            if (responseMsg.Success)
            {
                // 页面应该跳转至开始签证申请页面
                if (responseMsg.ExcuteCommand == RequestCommand.StartTakePhoto)
                {
                    Log.WriteAsync($"收到拍照模块消息, Guid={responseMsg.TID}, 拍照成功, 开始签证申请流程");
                    StartNewJob("签证申请", responseMsg.TID, responseMsg.OutParams);
                }
                if (responseMsg.ExcuteCommand == RequestCommand.ExitApp)
                {
                    Log.WriteAsync($"收到拍照模块消息, Guid={responseMsg.TID}, 开始退出并关闭系统.");
                    _appManager.Exit();
                    AsyncTask.StartDelayTask(3, () =>
                    {
                        this.Close();
                    }, this);
                }
            }
            else
            {
                if (responseMsg.ExcuteCommand == RequestCommand.StartTakePhoto)
                {
                    Log.WriteAsync($"收到拍照模块完成消息, 拍照失败, {responseMsg.Message}");
                    Log.WriteAsync("返回主页程序");
                    SwitchToModule(_appManager.HomeApp);
                }
                else
                {
                    Log.WriteAsync($"收到服务器动作执行失败消息, ExcuteCommand={responseMsg.ExcuteCommand}, {responseMsg.Message}");
                }
            }
        }
        #endregion

    }
}
